Imports System
Imports System.Data
Imports System.Collections
Imports System.Collections.Generic

Imports Framework

<Serializable(), CLSCompliant(True)> _
Partial Public Class CItem
    Inherits CBaseDynamic
    Implements IComparable(Of CItem)

#Region "Constructors"
    'Public (Copy Constructor)
    Public Sub New(ByVal original as CItem, target As CDataSrc)
        m_dataSrc = target
        m_itemName = original.ItemName
        m_itemDescription = original.ItemDescription
        m_itemStatusId = original.ItemStatusId
        m_itemCreatedByUserId = original.ItemCreatedByUserId
        m_itemAssignedToUserId = original.ItemAssignedToUserId
        m_itemAssignedToUserId2 = original.ItemAssignedToUserId2
        m_itemAssignedToUserId3 = original.ItemAssignedToUserId3
        m_itemAssignedToUserId4 = original.ItemAssignedToUserId4
        m_itemPriorityId = original.ItemPriorityId
        m_itemCategoryId = original.ItemCategoryId
        m_itemDateCreated = original.ItemDateCreated
        m_itemDateStarted = original.ItemDateStarted
        m_itemDateReviewed = original.ItemDateReviewed
        m_itemDateCompleted = original.ItemDateCompleted
        m_ItemEstimatedHours = original.ItemEstimatedHours
    End Sub

    'Protected (Datareader/Dataset)
    Protected Sub New(ByVal dataSrc As CDataSrc, ByVal dr As IDataReader)
        MyBase.New(dataSrc, dr)
    End Sub
    Protected Sub New(ByVal dataSrc As CDataSrc, ByVal dr As DataRow)
        MyBase.New(dataSrc, dr)
    End Sub
#End Region

#Region "Default Values"
    Protected Overrides Sub InitValues_Auto()
        'Null-Equivalent values (except String.Empty, as nulls tend to be inconvenient for string types)
        m_itemId = Integer.MinValue
        m_itemName = String.Empty
        m_itemDescription = String.Empty
        m_itemStatusId = Integer.MinValue
        m_itemCreatedByUserId = Integer.MinValue
        m_itemAssignedToUserId = Integer.MinValue
        m_itemAssignedToUserId2 = Integer.MinValue
        m_itemAssignedToUserId3 = Integer.MinValue
        m_itemAssignedToUserId4 = Integer.MinValue
        m_itemPriorityId = Integer.MinValue
        m_itemCategoryId = Integer.MinValue
        m_itemDateCreated = DateTime.MinValue
        m_itemDateStarted = DateTime.MinValue
        m_itemDateReviewed = DateTime.MinValue
        m_itemDateCompleted = DateTime.MinValue
        m_itemEstimatedHours = Double.NaN
    End Sub
#End Region

#Region "Members"
    Protected m_itemId As Integer
    Protected m_itemName As String
    Protected m_itemDescription As String
    Protected m_itemStatusId As Integer
    Protected m_itemCreatedByUserId As Integer
    Protected m_itemAssignedToUserId As Integer
    Protected m_itemAssignedToUserId2 As Integer
    Protected m_itemAssignedToUserId3 As Integer
    Protected m_itemAssignedToUserId4 As Integer
    Protected m_itemPriorityId As Integer
    Protected m_itemCategoryId As Integer
    Protected m_itemDateCreated As DateTime
    Protected m_itemDateStarted As DateTime
    Protected m_itemDateReviewed As DateTime
    Protected m_itemDateCompleted As DateTime
    Protected m_itemEstimatedHours As Double
#End Region

#Region "Properties - Column Values"
    'Primary Key Column (ReadOnly)
    Public ReadOnly Property [ItemId]() As Integer
        Get
            Return m_itemId
        End Get
    End Property

    'Table Columns (Read/Write)
    Public Property [ItemName]() As String
        Get
            Return m_itemName
        End Get
        Set(ByVal value As String)
            m_itemName = value
        End Set
    End Property
    Public Property [ItemDescription]() As String
        Get
            Return m_itemDescription
        End Get
        Set(ByVal value As String)
            m_itemDescription = value
        End Set
    End Property
    Public Property [ItemStatusId]() As Integer
        Get
            Return m_itemStatusId
        End Get
        Set(ByVal value As Integer)
            m_itemStatusId = value
        End Set
    End Property
    Public Property [ItemCreatedByUserId]() As Integer
        Get
            Return m_itemCreatedByUserId
        End Get
        Set(ByVal value As Integer)
            m_itemCreatedByUserId = value
        End Set
    End Property
    Public Property [ItemAssignedToUserId]() As Integer
        Get
            Return m_itemAssignedToUserId
        End Get
        Set(ByVal value As Integer)
            m_itemAssignedToUserId = value
        End Set
    End Property
    Public Property [ItemAssignedToUserId2]() As Integer
        Get
            Return m_itemAssignedToUserId2
        End Get
        Set(ByVal value As Integer)
            m_itemAssignedToUserId2 = value
        End Set
    End Property
    Public Property [ItemAssignedToUserId3]() As Integer
        Get
            Return m_itemAssignedToUserId3
        End Get
        Set(ByVal value As Integer)
            m_itemAssignedToUserId3 = value
        End Set
    End Property
    Public Property [ItemAssignedToUserId4]() As Integer
        Get
            Return m_itemAssignedToUserId3
        End Get
        Set(ByVal value As Integer)
            m_itemAssignedToUserId4 = value
        End Set
    End Property
    Public Property [ItemPriorityId]() As Integer
        Get
            Return m_itemPriorityId
        End Get
        Set(ByVal value As Integer)
            m_itemPriorityId = value
        End Set
    End Property
    Public Property [ItemCategoryId]() As Integer
        Get
            Return m_itemCategoryId
        End Get
        Set(ByVal value As Integer)
            m_itemCategoryId = value
        End Set
    End Property
    Public Property [ItemDateCreated]() As DateTime
        Get
            Return m_itemDateCreated
        End Get
        Set(ByVal value As DateTime)
            m_itemDateCreated = value
        End Set
    End Property
    Public Property [ItemDateStarted]() As DateTime
        Get
            Return m_itemDateStarted
        End Get
        Set(ByVal value As DateTime)
            m_itemDateStarted = value
        End Set
    End Property
    Public Property [ItemDateReviewed]() As DateTime
        Get
            Return m_itemDateReviewed
        End Get
        Set(ByVal value As DateTime)
            m_itemDateReviewed = value
        End Set
    End Property
    Public Property [ItemDateCompleted]() As DateTime
        Get
            Return m_itemDateCompleted
        End Get
        Set(ByVal value As DateTime)
            m_itemDateCompleted = value
        End Set
    End Property
    Public Property ItemEstimatedHours() As Double
        Get
            Return m_itemEstimatedHours
        End Get
        Set(ByVal value As Double)
            m_itemEstimatedHours = value
        End Set
    End Property

    'View Columns (ReadOnly)

#End Region

#Region "MustOverride Methods"
    'Schema Information
    Public Const TABLE_NAME As String = "tblItems"
    Public Const VIEW_NAME As String  = ""          'Used to override Me.ViewName
    Public Const ORDER_BY_COLS As String = "ItemID DESC" 'See the CompareTo method below (Sql-based sorting should match In-Memory sorting)
    Public Const SORTING_COLUMN As String = ""
    Public Overrides ReadOnly Property TableName() As String
        Get
            Return TABLE_NAME
        End Get
    End Property
    Protected Overrides ReadOnly Property OrderByColumns() As String
        Get
            Return ORDER_BY_COLS
        End Get
    End Property

    'CompareTo Interface (Default Sort Order)
    Public Function CompareTo(other As CItem) As Integer Implements IComparable(Of CItem).CompareTo
        Return Me.ItemID.CompareTo(other.ItemID) *-1
    End Function

    'Primary Key Information
    Public Const PRIMARY_KEY_NAME As String = "ItemId"
    Protected Overrides ReadOnly Property InsertPrimaryKey() As Boolean
        Get
            Return False
        End Get
    End Property
    Protected Overrides ReadOnly Property PrimaryKeyName() As String
        Get
            Return PRIMARY_KEY_NAME
        End Get
    End Property
    Protected Overrides Property PrimaryKeyValue() As Object
        Get
            Return m_itemId
        End Get
        Set(ByVal value As Object)
            m_itemId = CType(Value, Integer)
        End Set
    End Property

    'Factory Methods - Object
    Protected Overrides Function MakeFrom(ByVal row As DataRow) As CBase
        Return New CItem(Me.DataSrc, row)
    End Function
    Protected Overrides Function MakeFrom(ByVal dr As IDataReader) As CBase
        Return New CItem(Me.DataSrc, dr)
    End Function
    
    'Factory Methods - List
    Protected Overrides Function MakeList() As IList
        Return New CItemList
    End Function
    Protected Overrides Function MakeList(ByVal capacity As Integer) As IList
        Return New CItemList(capacity)
    End Function

    'Convert from ADO to .Net
    Protected Overrides Sub ReadColumns(ByVal dr As IDataReader)
        m_itemId = CAdoData.GetInt(dr, "ItemId")
        m_itemName = CAdoData.GetStr(dr, "ItemName")
        m_itemDescription = CAdoData.GetStr(dr, "ItemDescription")
        m_itemStatusId = CAdoData.GetInt(dr, "ItemStatusId")
        m_itemCreatedByUserId = CAdoData.GetInt(dr, "ItemCreatedByUserId")
        m_itemAssignedToUserId = CAdoData.GetInt(dr, "ItemAssignedToUserId")
        m_itemAssignedToUserId2 = CAdoData.GetInt(dr, "ItemAssignedToUserId2")
        m_itemAssignedToUserId3 = CAdoData.GetInt(dr, "ItemAssignedToUserId3")
        m_itemAssignedToUserId4 = CAdoData.GetInt(dr, "ItemAssignedToUserId4")
        m_itemPriorityId = CAdoData.GetInt(dr, "ItemPriorityId")
        m_itemCategoryId = CAdoData.GetInt(dr, "ItemCategoryId")
        m_itemDateCreated = CAdoData.GetDate(dr, "ItemDateCreated")
        m_itemDateStarted = CAdoData.GetDate(dr, "ItemDateStarted")
        m_itemDateReviewed = CAdoData.GetDate(dr, "ItemDateReviewed")
        m_itemDateCompleted = CAdoData.GetDate(dr, "ItemDateCompleted")
        m_itemEstimatedHours = CAdoData.GetDbl(dr, "ItemEstimatedHours")
    End Sub
    Protected Overrides Sub ReadColumns(ByVal dr As DataRow)
        m_itemId = CAdoData.GetInt(dr, "ItemId")
        m_itemName = CAdoData.GetStr(dr, "ItemName")
        m_itemDescription = CAdoData.GetStr(dr, "ItemDescription")
        m_itemStatusId = CAdoData.GetInt(dr, "ItemStatusId")
        m_itemCreatedByUserId = CAdoData.GetInt(dr, "ItemCreatedByUserId")
        m_itemAssignedToUserId = CAdoData.GetInt(dr, "ItemAssignedToUserId")
        m_itemAssignedToUserId2 = CAdoData.GetInt(dr, "ItemAssignedToUserId2")
        m_itemAssignedToUserId3 = CAdoData.GetInt(dr, "ItemAssignedToUserId3")
        m_itemAssignedToUserId4 = CAdoData.GetInt(dr, "ItemAssignedToUserId4")
        m_itemPriorityId = CAdoData.GetInt(dr, "ItemPriorityId")
        m_itemCategoryId = CAdoData.GetInt(dr, "ItemCategoryId")
        m_itemDateCreated = CAdoData.GetDate(dr, "ItemDateCreated")
        m_itemDateStarted = CAdoData.GetDate(dr, "ItemDateStarted")
        m_itemDateReviewed = CAdoData.GetDate(dr, "ItemDateReviewed")
        m_itemDateCompleted = CAdoData.GetDate(dr, "ItemDateCompleted")
        m_itemEstimatedHours = CAdoData.GetDbl(dr, "ItemEstimatedHours")
    End Sub

    'Parameters for Insert/Update    
    Protected Overrides Function ColumnNameValues() As CNameValueList
        Dim data As New CNameValueList
        data.Add("ItemId", NullVal(m_itemId))
        data.Add("ItemName", NullVal(m_itemName))
        data.Add("ItemDescription", NullVal(m_itemDescription))
        data.Add("ItemStatusId", NullVal(m_itemStatusId))
        data.Add("ItemCreatedByUserId", NullVal(m_itemCreatedByUserId))
        data.Add("ItemAssignedToUserId", NullVal(m_itemAssignedToUserId))
        data.Add("ItemAssignedToUserId2", NullVal(m_itemAssignedToUserId2))
        data.Add("ItemAssignedToUserId3", NullVal(m_itemAssignedToUserId3))
        data.Add("ItemAssignedToUserId4", NullVal(m_itemAssignedToUserId4))
        data.Add("ItemPriorityId", NullVal(m_itemPriorityId))
        data.Add("ItemCategoryId", NullVal(m_itemCategoryId))
        data.Add("ItemDateCreated", NullVal(m_itemDateCreated))
        data.Add("ItemDateStarted", NullVal(m_itemDateStarted))
        data.Add("ItemDateReviewed", NullVal(m_itemDateReviewed))
        data.Add("ItemDateCompleted", NullVal(m_itemDateCompleted))
        data.Add("ItemEstimatedHours", NullVal(m_itemEstimatedHours))
        Return data
    End Function
#End Region

#Region "Queries - SelectAll/SelectWhere (inherited methods, cast only)"
    'Select Queries - Non-Paged
    Public Shadows Function SelectAll() As CItemList
        Return CType(MyBase.SelectAll(), CItemList)
    End Function
    Public Shadows Function SelectAll(ByVal orderBy As String) As CItemList
        Return CType(MyBase.SelectAll(orderBy), CItemList)
    End Function
    Protected Shadows Function SelectWhere(ByVal colName As String, ByVal sign As ESign, ByVal colValue As Object) As CItemList
        Return CType(MyBase.SelectWhere(colName, sign, colValue), CItemList)
    End Function
    Protected Shadows Function SelectWhere(ByVal where As CCriteria) As CItemList
        Return CType(MyBase.SelectWhere(where), CItemList)
    End Function
    Protected Shadows Function SelectWhere(ByVal where As CCriteriaList) As CItemList
        Return CType(MyBase.SelectWhere(where), CItemList)
    End Function
    Protected Shadows Function SelectWhere(ByVal where As CCriteriaList, ByVal tableNameOrJoinExpression As String) As CItemList
        Return CType(MyBase.SelectWhere(where, tableNameOrJoinExpression, Me.OrderByColumns), CItemList)
    End Function
    Protected Shadows Function SelectWhere(ByVal where As CCriteriaList, ByVal tableNameOrJoinExpression As String, ByVal orderBy As String) As CItemList
        Return CType(MyBase.SelectWhere(where, tableNameOrJoinExpression, orderBy), CItemList)
    End Function
    <Obsolete("Arbitrary where-clause is not necessary portable or safe from sql injection attacks. Consider using the parameterised query interfaces")> _
    Protected Shadows Function SelectWhere(ByVal unsafeWhereClause As String) As CItemList
        Return CType(MyBase.SelectWhere(unsafeWhereClause), CItemList)
    End Function
    Protected Shadows Function SelectById(ByVal itemId As Integer) As CItemList
        Return CType(MyBase.SelectById(itemId), CItemList)
    End Function
    Protected Shadows Function SelectByIds(ByVal ids As List(Of Integer)) As CItemList
        Return CType(MyBase.SelectByIds(ids), CItemList)
    End Function

    'Select Queries - Paged
    Public Shadows Function SelectAll(ByVal pi As CPagingInfo) As CItemList
        Return CType(MyBase.SelectAll(pi), CItemList)
    End Function
    Protected Shadows Function SelectWhere(ByVal pi As CPagingInfo, ByVal colName As String, ByVal sign As ESign, ByVal colValue As Object) As CItemList
        Return CType(MyBase.SelectWhere(pi, colName, sign, colValue), CItemList)
    End Function
    Protected Shadows Function SelectWhere(ByVal pi As CPagingInfo, ByVal criteria As CCriteria) As CItemList
        Return CType(MyBase.SelectWhere(pi, criteria), CItemList)
    End Function
    Protected Shadows Function SelectWhere(ByVal pi As CPagingInfo, ByVal criteria As CCriteriaList) As CItemList
        Return CType(MyBase.SelectWhere(pi, criteria), CItemList)
    End Function
    Protected Shadows Function SelectWhere(ByVal pi As CPagingInfo, ByVal criteria As CCriteriaList, ByVal tableViewOrJoinExpr As String) As CItemList
        Return CType(MyBase.SelectWhere(pi, criteria, tableViewOrJoinExpr), CItemList)
    End Function
    Protected Shadows Function SelectByIds(ByVal pi As CPagingInfo, ByVal ids As List(Of Integer)) As CItemList
        Return CType(MyBase.SelectByIds(pi, ids), CItemList)
    End Function

    'Select Queries - Transactional (Friend-scoped for use in cascade-deletes)
    Friend Shadows Function SelectAll(ByVal tx As IDbTransaction) As CItemList
        Return CType(MyBase.SelectAll(tx), CItemList)
    End Function
    Friend Shadows Function SelectWhere(ByVal columnName As String, columnValue As Object, ByVal tx As IDbTransaction) As CItemList
        Return CType(MyBase.SelectWhere(columnName, columnValue, tx), CItemList)
    End Function
    Friend Shadows Function SelectWhere(ByVal columnName As String, sign As ESign, columnValue As Object, ByVal tx As IDbTransaction) As CItemList
        Return CType(MyBase.SelectWhere(columnName, sign, columnValue, tx), CItemList)
    End Function
    Friend Shadows Function SelectWhere(ByVal criteria As CCriteria, ByVal tx As IDbTransaction) As CItemList
        Return CType(MyBase.SelectWhere(criteria, tx), CItemList)
    End Function
    Friend Shadows Function SelectWhere(ByVal criteria As CCriteriaList, ByVal tx As IDbTransaction) As CItemList
        Return CType(MyBase.SelectWhere(criteria, tx), CItemList)
    End Function
    Friend Shadows Function SelectWhere(ByVal criteria As CCriteriaList, ByVal tableOrJoin As String, ByVal tx As IDbTransaction) As CItemList
        Return CType(MyBase.SelectWhere(criteria, tableOrJoin, tx), CItemList)
    End Function
    Friend Shadows Function SelectWhere(ByVal criteria As CCriteriaList, ByVal tableOrJoin As String, ByVal orderBy As String, ByVal tx As IDbTransaction) As CItemList
        Return CType(MyBase.SelectWhere(criteria, tableOrJoin, orderBy, tx), CItemList)
    End Function
    Friend Shadows Function SelectById(ByVal itemId As Integer, ByVal tx As IDbTransaction) As CItemList
        Return CType(MyBase.SelectById(itemId, tx), CItemList)
    End Function
    Friend Shadows Function SelectByIds(ByVal ids As List(Of Integer), ByVal tx As IDbTransaction) As CItemList
        Return CType(MyBase.SelectByIds(ids, tx), CItemList)
    End Function
    
    'Select Queries - Stored Procedures
    Protected Overloads Function MakeList(ByVal storedProcName As String, ByVal txOrNull As IDbTransaction) As CItemList
        Return CType(MyBase.MakeList(storedProcName,         txOrNull), CItemList)
    End Function
    Protected Overloads Function MakeList(ByVal storedProcName As String, ByVal params As Object(), ByVal txOrNull As IDbTransaction) As CItemList
        Return CType(MyBase.MakeList(storedProcName, params, txOrNull), CItemList)
    End Function
    Protected Overloads Function MakeList(ByVal storedProcName As String, ByVal params As CNameValueList, ByVal txOrNull As IDbTransaction) As CItemList
        Return CType(MyBase.MakeList(storedProcName, params, txOrNull), CItemList)
    End Function
    Protected Overloads Function MakeList(ByVal storedProcName As String, ByVal params As List(Of Object), ByVal txOrNull As IDbTransaction) As CItemList
        Return CType(MyBase.MakeList(storedProcName, params, txOrNull), CItemList)
    End Function
    Protected Overloads Function MakeList(ByVal storedProcName As String, ByVal param1 As Integer, ByVal txOrNull As IDbTransaction) As CItemList
        Return CType(MyBase.MakeList(storedProcName, param1, txOrNull), CItemList)
    End Function
    Protected Overloads Function MakeList(ByVal storedProcName As String, ByVal param1 As String, ByVal txOrNull As IDbTransaction) As CItemList
        Return CType(MyBase.MakeList(storedProcName, param1, txOrNull), CItemList)
    End Function

    'Query Results
    Protected Overloads Function MakeList(ByVal ds As DataSet) As CItemList
        Return CType(MyBase.MakeList(ds), CItemList)
    End Function
    Protected Overloads Function MakeList(ByVal dt As DataTable) As CItemList
        Return CType(MyBase.MakeList(dt), CItemList)
    End Function
    Protected Overloads Function MakeList(ByVal rows As DataRowCollection) As CItemList
        Return CType(MyBase.MakeList(rows), CItemList)
    End Function
    Protected Overloads Function MakeList(ByVal dr As IDataReader) As CItemList
        Return CType(MyBase.MakeList(dr), CItemList)
    End Function
    Protected Overloads Function MakeList(ByVal drOrDs As Object) As CItemList
        Return CType(MyBase.MakeList(drOrDs), CItemList)
    End Function
    Protected Overloads Function MakeList(ByVal gzip As Byte()) As CItemList
        Return CType(MyBase.MakeList(gzip), CItemList)
    End Function
#End Region

#Region "Queries - SelectBy[FK] (user-nominated fk/bool columns)"
    'Note: These methods should only be used for cascade-deletes, or initialising the cache. Use CItem.Cache.GetBy... for reqular queries
    
    'Non-Paged
    Protected Function SelectByStatusId(ByVal itemStatusId As Integer) As CItemList
        Return SelectWhere(new CCriteriaList("ItemStatusId", itemStatusId))
    End Function
    Protected Function SelectByCreatedByUserId(ByVal itemCreatedByUserId As Integer) As CItemList
        Return SelectWhere(new CCriteriaList("ItemCreatedByUserId", itemCreatedByUserId))
    End Function
    Protected Function SelectByAssignedToUserId(ByVal itemAssignedToUserId As Integer) As CItemList
        Return SelectWhere(new CCriteriaList("ItemAssignedToUserId", itemAssignedToUserId))
    End Function
    Protected Function SelectByAssignedToUserId2(ByVal itemAssignedToUserId2 As Integer) As CItemList
        Return SelectWhere(new CCriteriaList("ItemAssignedToUserId2", itemAssignedToUserId2))
    End Function
    Protected Function SelectByAssignedToUserId3(ByVal itemAssignedToUserId3 As Integer) As CItemList
        Return SelectWhere(new CCriteriaList("ItemAssignedToUserId3", itemAssignedToUserId3))
    End Function
    Protected Function SelectByAssignedToUserId4(ByVal itemAssignedToUserId4 As Integer) As CItemList
        Return SelectWhere(New CCriteriaList("ItemAssignedToUserId4", ItemAssignedToUserId3))
    End Function
    Protected Function SelectByPriorityId(ByVal itemPriorityId As Integer) As CItemList
        Return SelectWhere(new CCriteriaList("ItemPriorityId", itemPriorityId))
    End Function
    Protected Function SelectByCategoryId(ByVal itemCategoryId As Integer) As CItemList
        Return SelectWhere(new CCriteriaList("ItemCategoryId", itemCategoryId))
    End Function

    'Paged
    Protected Function SelectByStatusId(pi as CPagingInfo, ByVal itemStatusId As Integer) As CItemList
        Return SelectWhere(pi, New CCriteriaList("ItemStatusId", itemStatusId))
    End Function
    Protected Function SelectByCreatedByUserId(pi as CPagingInfo, ByVal itemCreatedByUserId As Integer) As CItemList
        Return SelectWhere(pi, New CCriteriaList("ItemCreatedByUserId", itemCreatedByUserId))
    End Function
    Protected Function SelectByAssignedToUserId(pi as CPagingInfo, ByVal itemAssignedToUserId As Integer) As CItemList
        Return SelectWhere(pi, New CCriteriaList("ItemAssignedToUserId", itemAssignedToUserId))
    End Function
    Protected Function SelectByAssignedToUserId2(pi as CPagingInfo, ByVal itemAssignedToUserId2 As Integer) As CItemList
        Return SelectWhere(pi, New CCriteriaList("ItemAssignedToUserId2", itemAssignedToUserId2))
    End Function
    Protected Function SelectByAssignedToUserId3(pi as CPagingInfo, ByVal itemAssignedToUserId3 As Integer) As CItemList
        Return SelectWhere(pi, New CCriteriaList("ItemAssignedToUserId3", itemAssignedToUserId3))
    End Function
    Protected Function SelectByAssignedToUserId4(pi As CPagingInfo, ByVal itemAssignedToUserId4 As Integer) As CItemList
        Return SelectWhere(pi, New CCriteriaList("ItemAssignedToUserId4", itemAssignedToUserId4))
    End Function
    Protected Function SelectByPriorityId(pi as CPagingInfo, ByVal itemPriorityId As Integer) As CItemList
        Return SelectWhere(pi, New CCriteriaList("ItemPriorityId", itemPriorityId))
    End Function
    Protected Function SelectByCategoryId(pi as CPagingInfo, ByVal itemCategoryId As Integer) As CItemList
        Return SelectWhere(pi, New CCriteriaList("ItemCategoryId", itemCategoryId))
    End Function

    'Count
    Protected Function SelectCountByStatusId(ByVal itemStatusId As Integer) As Integer
        Return SelectCount(New CCriteriaList("ItemStatusId", itemStatusId))
    End Function
    Protected Function SelectCountByCreatedByUserId(ByVal itemCreatedByUserId As Integer) As Integer
        Return SelectCount(New CCriteriaList("ItemCreatedByUserId", itemCreatedByUserId))
    End Function
    Protected Function SelectCountByAssignedToUserId(ByVal itemAssignedToUserId As Integer) As Integer
        Return SelectCount(New CCriteriaList("ItemAssignedToUserId", itemAssignedToUserId))
    End Function
    Protected Function SelectCountByAssignedToUserId2(ByVal itemAssignedToUserId2 As Integer) As Integer
        Return SelectCount(New CCriteriaList("ItemAssignedToUserId2", itemAssignedToUserId2))
    End Function
    Protected Function SelectCountByAssignedToUserId3(ByVal itemAssignedToUserId3 As Integer) As Integer
        Return SelectCount(New CCriteriaList("ItemAssignedToUserId3", itemAssignedToUserId3))
    End Function
    Protected Function SelectCountByPriorityId(ByVal itemPriorityId As Integer) As Integer
        Return SelectCount(New CCriteriaList("ItemPriorityId", itemPriorityId))
    End Function
    Protected Function SelectCountByCategoryId(ByVal itemCategoryId As Integer) As Integer
        Return SelectCount(New CCriteriaList("ItemCategoryId", itemCategoryId))
    End Function

    'Transactional
    Friend Function SelectByStatusId(ByVal itemStatusId As Integer, tx As IDbTransaction) As CItemList
        Return SelectWhere(New CCriteriaList("ItemStatusId", itemStatusId), tx)
    End Function
    Friend Function SelectByCreatedByUserId(ByVal itemCreatedByUserId As Integer, tx As IDbTransaction) As CItemList
        Return SelectWhere(New CCriteriaList("ItemCreatedByUserId", itemCreatedByUserId), tx)
    End Function
    Friend Function SelectByAssignedToUserId(ByVal itemAssignedToUserId As Integer, tx As IDbTransaction) As CItemList
        Return SelectWhere(New CCriteriaList("ItemAssignedToUserId", itemAssignedToUserId), tx)
    End Function
    Friend Function SelectByAssignedToUserId2(ByVal itemAssignedToUserId2 As Integer, tx As IDbTransaction) As CItemList
        Return SelectWhere(New CCriteriaList("ItemAssignedToUserId2", itemAssignedToUserId2), tx)
    End Function
    Friend Function SelectByAssignedToUserId3(ByVal itemAssignedToUserId3 As Integer, tx As IDbTransaction) As CItemList
        Return SelectWhere(New CCriteriaList("ItemAssignedToUserId3", itemAssignedToUserId3), tx)
    End Function
    Friend Function SelectByPriorityId(ByVal itemPriorityId As Integer, tx As IDbTransaction) As CItemList
        Return SelectWhere(New CCriteriaList("ItemPriorityId", itemPriorityId), tx)
    End Function
    Friend Function SelectByCategoryId(ByVal itemCategoryId As Integer, tx As IDbTransaction) As CItemList
        Return SelectWhere(New CCriteriaList("ItemCategoryId", itemCategoryId), tx)
    End Function
#End Region

#Region "Static - Cache Implementation"
    Public Shared Property Cache() As CItemList
        Get
            Cache = CType(CCache.Get(CACHE_KEY), CItemList)
            If IsNothing(cache) Then
                SyncLock (CACHE_KEY)
                    Cache = CType(CCache.Get(CACHE_KEY), CItemList)
                    If IsNothing(cache) Then
                        Cache = LoadCache()
                        CItem.Cache = Cache
                    End If
                End SyncLock
            End If
            Return cache
        End Get
        Set(ByVal value As CItemList)
            SetCache(value)
        End Set
    End Property

    'Change Management:
    'Clone, modify, and then replace the cache (threadsafe for anything iterating the collection)
    'Note that internal indices are dicarded each time unless handled in constructor and add/remove overrides
    Protected Overrides Sub CacheDelete()
        If CacheIsNull Then Exit Sub
        SyncLock (CACHE_KEY)
            Dim temp As CItemList = New CItemList(Cache)
            Dim size As Integer = temp.Count
            temp.Remove(Me)
            If size = temp.Count Then 'Remove might fail If cache was refreshed with New instances. Use old index                    
                temp.Remove(CacheGetById(temp))
            End If
            SetCache(temp)
        End SyncLock
    End Sub
    Protected Overrides Sub CacheInsert()
        If CacheIsNull Then Exit Sub
        SyncLock (CACHE_KEY)
            Dim temp As CItemList = New CItemList(Cache)
            temp.Add(Me)
            SetCache(temp)
        End SyncLock
    End Sub
    Protected Overrides Sub CacheUpdate()
        If CacheIsNull Then Exit Sub
        SyncLock (CACHE_KEY)
            Dim temp As CItemList = New CItemList(Cache)
            If Not temp.Contains(Me) Then
                temp.Remove(CacheGetById(temp))
                temp.Add(Me)
            End If
            SetCache(temp)
        End SyncLock
    End Sub
    Protected Overrides Sub CacheClear()
        Cache = Nothing
    End Sub
    Public Shared ReadOnly Property CacheIsNull() As Boolean
        Get
            Return IsNothing(CCache.Get(CACHE_KEY))
        End Get
    End Property
#End Region

#Region "ToXml"
    Protected Overrides Sub ToXml_Autogenerated(ByVal w As System.Xml.XmlWriter)
        Store(w, "ItemId", Me.ItemId)
        Store(w, "ItemName", Me.ItemName)
        Store(w, "ItemDescription", Me.ItemDescription)
        Store(w, "ItemStatusId", Me.ItemStatusId)
        Store(w, "ItemCreatedByUserId", Me.ItemCreatedByUserId)
        Store(w, "ItemAssignedToUserId", Me.ItemAssignedToUserId)
        Store(w, "ItemAssignedToUserId2", Me.ItemAssignedToUserId2)
        Store(w, "ItemAssignedToUserId3", Me.ItemAssignedToUserId3)
        Store(w, "ItemPriorityId", Me.ItemPriorityId)
        Store(w, "ItemCategoryId", Me.ItemCategoryId)
        Store(w, "ItemDateCreated", Me.ItemDateCreated)
        Store(w, "ItemDateStarted", Me.ItemDateStarted)
        Store(w, "ItemDateReviewed", Me.ItemDateReviewed)
        Store(w, "ItemDateCompleted", Me.ItemDateCompleted)
        Store(w, "ItemEstimatedHours", Me.ItemEstimatedHours)
    End Sub
#End Region


End Class